package com.shenke.ihgateway.blackfilter;

import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
public class NacosListener implements InitializingBean {

    //@NacosInjected
    @Resource
    private ConfigService configService;

    @Value("${spring.cloud.nacos.config.data-id}")
    private String dataId;

    @Value("${spring.cloud.nacos.config.group}")
    private String group;

    @Override
    public void afterPropertiesSet() throws Exception {
        // 记录日志，表示 nacos 监听器已启动
        log.info("nacos 监听器启动");
        if (configService == null) {
            // 记录日志，表示 configService 为空
            log.info("configService is null");
            // 防止空指针异常，提前返回
            return;
        }
        // 从 nacos 配置服务获取配置信息，并注册监听器
        String config = configService.getConfigAndSignListener(dataId, group, 3000L, new Listener() {
            // 自定义线程工厂，用于创建线程池中的线程
            final ThreadFactory threadFactory = new ThreadFactory() {
                private final AtomicInteger poolNumber = new AtomicInteger(1);
                @Override
                public Thread newThread(@NotNull Runnable r) {
                    // 创建新线程，并设置线程名称
                    Thread thread = new Thread(r);
                    thread.setName("refresh-ThreadPool" + poolNumber.getAndIncrement());
                    return thread;
                }
            };
            // 创建固定大小为 1 的线程池，使用自定义的线程工厂
            final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);

            // 返回自定义的线程池，用于异步处理配置信息变化
            @Override
            public Executor getExecutor() {
                return executorService;
            }

            // 接收配置信息变化，并处理黑名单更新逻辑
            @Override
            public void receiveConfigInfo(String configInfo) {
                // 记录日志，表示监听到配置信息变化
                log.info("监听到配置信息变化：{}", configInfo);
                // 重建黑名单
                BlackIpUtils.rebuildBlackIp(configInfo);
            }
        });
        // 初始化黑名单
        BlackIpUtils.rebuildBlackIp(config);
    }
}
